package Connectivity; import java.util.ArrayList; import Command.LDrawPart; import Common.Matrix4; import Common.Vector3f; public class Hinge extends Connectivity { float FlipLimMax; float FlipLimMin; float LimMax; float LimMin; int oriented; String tag; public float getFlipLimMax() { return FlipLimMax; } public void setFlipLimMax(String flipLimMax) { FlipLimMax = Float.parseFloat(flipLimMax); } public float getFlipLimMin() { return FlipLimMin; } public void setFlipLimMin(String flipLimMin) { FlipLimMin = Float.parseFloat(flipLimMin); } public float getLimMax() { return LimMax; } public void setLimMax(String limMax) { LimMax = Float.parseFloat(limMax); } public float getLimMin() { return LimMin; } public void setLimMin(String limMin) { LimMin = Float.parseFloat(limMin); } public int getoriented() { return oriented; } public void setoriented(String oriented) { this.oriented = Integer.parseInt(oriented); } public String gettag() { return tag; } public void settag(String tag) { this.tag = tag; } @Override public String toString() { if (tag != null) { return super.toString(String.format("%f %f %f %f %d %s", FlipLimMax, FlipLimMin, LimMax, LimMin, oriented, tag)); } else { return super.toString(String.format("%f %f %f %f %d", FlipLimMax, FlipLimMin, LimMax, LimMin, oriented)); } } @Override public int parseString(String[] line) { int size = super.parseString(line); setFlipLimMax(line[size + 1]); setFlipLimMin(line[size + 2]); setLimMax(line[size + 3]); setLimMin(line[size + 4]); setoriented(line[size + 5]); settag(line[size + 6]); return 0; } @Override public String getName() { return "Hinge"; } @Override public Matrix4 getRotationMatrixForConnection(Connectivity existingConn, Matrix4 initialTransformMatrixOfPart) { Matrix4 newMatrix = new Matrix4(initialTransformMatrixOfPart); newMatrix.element[3][0] = newMatrix.element[3][1] = newMatrix.element[3][2] = 0; LDrawPart existingPart = existingConn.getParent(); Matrix4 existingConnTransformMatrix = Matrix4.multiply( existingConn.getTransformMatrix(), existingPart.transformationMatrix()); Matrix4 candidate = Matrix4.multiply(Matrix4.inverse(transformMatrix), existingConnTransformMatrix); Vector3f rotationVector = getRotationVector(candidate); Matrix4 inverseOfCandidate = new Matrix4(candidate); inverseOfCandidate.rotate((float) Math.toRadians(180), rotationVector); Vector3f directionVector_init = getDirectionVector(initialTransformMatrixOfPart); Vector3f directionVector_candidate = getDirectionVector(candidate); Vector3f directionVector_icandidate = getDirectionVector(inverseOfCandidate); float dirDiff = (float) Math.acos(directionVector_init .dot(directionVector_candidate) / directionVector_candidate.length() / directionVector_init.length()); float dirDiff2 = (float) Math.acos(directionVector_init .dot(directionVector_icandidate) / directionVector_icandidate.length() / directionVector_init.length()); if (directionVector_init.equals(directionVector_candidate)) return newMatrix; else if (directionVector_init.equals(directionVector_icandidate)) return newMatrix; else if (dirDiff > dirDiff2) candidate = inverseOfCandidate; ArrayList<Matrix4> candidateForRotation = new ArrayList<Matrix4>(); candidateForRotation.add(candidate); for (int i = 0; i < 3; i++) { candidate = new Matrix4(candidate); candidate.rotate((float) Math.toRadians(90), existingConn.getDirectionVector()); candidateForRotation.add(candidate); } dirDiff = -1; // System.out.println("#########################"); for (Matrix4 matrix : candidateForRotation) { dirDiff2 = matrix .getDifferentValueForRotation(initialTransformMatrixOfPart); if (dirDiff < 0) { dirDiff = dirDiff2; newMatrix = matrix; } else if (dirDiff > dirDiff2 + 0.1f) { dirDiff = dirDiff2; newMatrix = matrix; } } newMatrix.element[3][0] = newMatrix.element[3][1] = newMatrix.element[3][2] = 0; return newMatrix; } private Vector3f getRotationVector(Matrix4 candidate) { Vector3f directionVector = getDirectionVector(candidate); // System.out.println("DirectionVector: "+directionVector); Vector3f rotationVector = null; switch (Direction6T.getDirectionOfTransformMatrix(Matrix4.multiply( transformMatrix, candidate))) { case X_Minus: case X_Plus: rotationVector = directionVector.cross(new Vector3f(0, 1, 0)); if (rotationVector.equals(new Vector3f())) rotationVector = new Vector3f(0, 1, 0); break; case Y_Minus: case Y_Plus: rotationVector = directionVector.cross(new Vector3f(0, 0, 1)); if (rotationVector.equals(new Vector3f())) rotationVector = new Vector3f(0, 0, 1); break; case Z_Minus: case Z_Plus: rotationVector = directionVector.cross(new Vector3f(1, 0, 0)); if (rotationVector.equals(new Vector3f())) rotationVector = new Vector3f(1, 0, 0); break; } // System.out.println("Rotation Vector: "+rotationVector); return rotationVector; } }